/**
 * @file 轨迹查看器Hook
 * @description 提供完整的轨迹数据管理、渲染和播放控制功能
 * @date 2024-08-21
 */

// @ts-ignore - uni-app环境下Vue导入需要忽略类型检查
import { ref, computed, Ref } from 'vue';
import { getTrackData } from '@/api/track';
import { formatDistance } from '@/utils/format/distance';
// @ts-ignore - 处理类型检查问题
import { calculateBMapTrackDistance } from '@/utils/format/geo';
import { convertTrackPointsForBMap } from '@/utils/map/track-utils';
import { logger } from '@/utils/system/logger';
import { useTrackAnimation } from './useTrackAnimation';

import type { TrackQueryParams, TrackPointsData, TrackPoint } from '@/types/track';

export interface TrackViewerOptions {
  /** 是否自动播放 */
  autoPlay?: boolean;
  /** 是否激活日期选择 */
  enableDateSelection?: boolean;
}

/**
 * 获取当天的时间范围
 * @returns 包含开始和结束时间的对象
 */
function getTodayRange(): { start: string, end: string } {
  const now = new Date();
  const today = now.toISOString().split('T')[0];
  return {
    start: `${today}T00:00:00`,
    end: now.toISOString()
  };
}

// 轨迹状态映射
const TRACK_STATUS_LOG_MAP: Record<number, string> = {
  1: '轨迹开始播放', // PLAY
  3: '轨迹继续播放', // RESUME
  2: '轨迹暂停播放', // PAUSE
  4: '轨迹停止播放', // STOP
  5: '轨迹播放完成', // FINISH
  0: '轨迹初始化完成' // INIT
};

/**
 * 轨迹查看器Hook - 合并了原useTrackManagement和useTrackViewer
 * 提供轨迹数据加载、渲染、播放和控制功能
 */
export function useTrackViewer(options: TrackViewerOptions = {}) {
  // =================== 状态管理 ===================
  
  // 轨迹查询状态
  const startTime = ref('');
  const endTime = ref('');
  const shouldLoadTrack = ref(false);
  const deviceId = ref('');
  
  // 轨迹数据状态
  const track = ref<any>(null);
  const trackLoaded = ref(false);
  const loading = ref(false);
  const error = ref<string | null>(null);
  const trackPoints = ref<TrackPoint[]>([]);
  const trackPointsCount = ref(0);
  const totalDistance = ref(0);
  const followingEnabled = ref(false);
  
  // 播放控制状态
  const isPlaying = ref(false);
  const currentIndex = ref(0);
  const playSpeed = ref(1);
  
  // 视图控制
  const showTrackViewer = ref(false);
  
  // 使用轨迹动画控制hook
  const { 
    trackLine,
    setTrackLine,
    startAnimation,
    pauseAnimation,
    resumeAnimation,
    stopAnimation,
    clearTrack
  } = useTrackAnimation();
  
  // 计算属性
  const formattedDistance = computed(() => formatDistance(totalDistance.value));
  
  // =================== 数据管理方法 ===================
  
  /**
   * 重置轨迹数据和加载状态
   */
  const resetTrackData = () => {
    trackPoints.value = [];
    shouldLoadTrack.value = false;
    trackLoaded.value = false;
    error.value = null;
    currentIndex.value = 0;
    isPlaying.value = false;
  };
  
  /**
   * 准备轨迹查询
   * @param id 设备ID
   */
  const prepareTrackQuery = (id?: string) => {
    // 确保时间范围已设置
    if (!startTime.value || !endTime.value) {
      const range = getTodayRange();
      startTime.value = range.start;
      endTime.value = range.end;
    }

    // 如果已有选中设备，清除轨迹并准备查询
    if (id) {
      deviceId.value = id;
      resetTrackData();
      shouldLoadTrack.value = true;
    }
  };

  /**
   * 处理轨迹错误
   * @param message 错误信息
   * @param error 原始错误对象
   * @param context 额外上下文信息
   */
  function handleTrackError(message: string, error?: any, context: Record<string, any> = {}): void {
    // 记录日志
    logger.error(message, error, { 
      component: 'TrackViewer',
      ...context
    });
    
    // 设置错误状态
    error.value = error instanceof Error ? error.message : message;
    
    // 显示用户提示
    uni.showToast({
      title: message,
      icon: 'error',
      duration: 2000
    });
  }
  
  /**
   * 获取轨迹数据
   * @param params 查询参数
   * @returns 轨迹数据
   */
  async function fetchTrackData(params: TrackQueryParams): Promise<any> {
    // 验证参数
    if (!params.deviceId || !params.startTime || !params.endTime) {
      handleTrackError('缺少必要的轨迹查询参数', null, { params });
      return null;
    }
    
    try {
      loading.value = true;
      error.value = null;
      
      // 调用API获取轨迹数据
      const response = await getTrackData(params);
      
      // 检查API响应和数据
      if (!response.success || !response.data?.tracks?.length) {
        const errorMsg = !response.success 
          ? (response.message ?? '获取轨迹数据失败')
          : '轨迹数据为空';
      
        const isNoData = response.success && !response.data?.tracks?.length;
        
        // 空数据按警告处理
        if (isNoData) {
          logger.warn('轨迹数据为空', {
            component: 'TrackViewer',
            deviceId: params.deviceId,
            timeRange: `${params.startTime} - ${params.endTime}`
          });
          
          uni.showToast({
            title: '未找到轨迹数据',
            icon: 'none',
            duration: 2000
          });
        } else {
          // 失败按错误处理
          handleTrackError(errorMsg, null, { response });
        }
        
        error.value = errorMsg;
        return null;
      }
      
      // 处理轨迹点数据
      const points = response.data.tracks;
      trackPointsCount.value = points.length;
      trackPoints.value = points;
      
      // 记录日志-轨迹数据获取成功
      logger.info('轨迹数据获取成功', {
        component: 'TrackViewer',
        deviceId: params.deviceId,
        pointsCount: points.length
      });
      
      // 计算总距离
      totalDistance.value = calculateBMapTrackDistance(points);
      
      // 转换轨迹点格式并绘制轨迹
      const trackPointsData = convertTrackPointsForBMap(points);
      
      // 返回处理后的数据
      return {
        points,
        trackPointsData,
        distance: totalDistance.value
      };
    } catch (err) {
      handleTrackError('获取轨迹数据异常', err, {
        startTime: params.startTime,
        endTime: params.endTime
      });
      return null;
    } finally {
      loading.value = false;
    }
  }
  
  /**
   * 加载轨迹数据
   */
  async function loadTrackData(): Promise<void> {
    if (!deviceId.value) {
      logger.warn('未设置设备ID，无法加载轨迹', { component: 'TrackViewer' });
      return;
    }
    
    const params: TrackQueryParams = {
      deviceId: deviceId.value,
      startTime: startTime.value,
      endTime: endTime.value
    };
    
    const result = await fetchTrackData(params);
    
    if (result) {
      trackPoints.value = result.points;
    }
  }

  // =================== 轨迹渲染方法 ===================
  
  /**
   * 绘制轨迹
   * @param trackPointsData 轨迹点数据
   * @param trackInstance 轨迹实例
   * @param mapRef 地图引用
   */
  async function drawTrack(trackPointsData: TrackPointsData, trackInstance: any, mapRef: Ref<any>): Promise<void> {
    if (!trackInstance) {
      logger.error('轨迹图层未创建', { component: 'TrackViewer' });
      return;
    }
    
    try {
      // 创建轨迹线
      const localTrack = new window.Track.LocalTrack({
        trackPath: trackPointsData.trackPoints,
        duration: 60, // 动画持续时间，秒
        style: {
          sequence: true,
          marginLength: 32,
          arrowColor: '#fff',
          strokeTextureUrl: 'https://mapopen-pub-jsapi.bj.bcebos.com/jsapiGlgeo/img/down.png',
          strokeTextureWidth: 64,
          strokeTextureHeight: 32,
          traceColor: [27, 142, 236]
        },
        linearTexture: [[0, '#f45e0c'], [0.5, '#f6cd0e'], [1, '#2ad61d']],
        gradientColor: trackPointsData.colorOffset
      });
      
      // 将trackLine设置到hook中
      setTrackLine(localTrack);
      
      // 添加轨迹状态变化事件
      trackLine.value.on(window.Track.LineCodes.STATUS, (status: number) => 
        handleTrackStatus(status, trackLine.value, mapRef)
      );
      
      // 添加到图层
      trackInstance.addTrackLine(trackLine.value);
      trackInstance.focusTrack(trackLine.value);
      
      // 添加移动点(车辆)，如果有轨迹点
      if (trackPointsData.trackPoints.length > 0) {
        addMovePoint(trackPointsData.trackPoints[0], mapRef);
        
        // 显式设置地图中心到第一个点
        const firstPoint = trackPointsData.trackPoints[0];
        if (firstPoint?.getPoint && mapRef?.value?.map) {
          const point = firstPoint.getPoint();
          logger.info('设置地图中心点到轨迹起点', { 
            component: 'TrackViewer',
            point: `${point.lng},${point.lat}` 
          });
          
          mapRef.value.map.setCenter(point);
          // 设置适当的缩放级别以确保轨迹点可见
          mapRef.value.map.setZoom(16);
        }
      }
      
      trackLoaded.value = true;
    } catch (err) {
      handleTrackError('绘制轨迹失败', err);
    }
  }

  /**
   * 添加移动点(车辆)到轨迹
   * @param firstPoint 第一个轨迹点
   * @param mapRef 地图引用
   */
  function addMovePoint(firstPoint: any, mapRef: Ref<any>): void {
    if (firstPoint?.getPoint && trackLine.value) {
      const movePoint = new window.Track.GroundPoint({
        point: firstPoint.getPoint(),
        style: {
          url: 'https://mapopen-pub-jsapi.bj.bcebos.com/jsapiGlgeo/img/car.png',
          level: 18,
          scale: 1,
          size: new window.BMapGL.Size(16, 32),
          anchor: new window.BMapGL.Size(0.5, 0.5),
        }
      });
      
      trackLine.value.setMovePoint(movePoint);
      
      // 添加移动点移动事件监听
      trackLine.value.on('movepoint-move', (e: any) => {
        if (followingEnabled.value && mapRef?.value?.map) {
          mapRef.value.map.setCenter(e.point);
        }
      });
    }
  }
  
  /**
   * 处理轨迹状态变化
   * @param status 轨迹状态码
   * @param trackLineInstance 轨迹线实例
   * @param mapRef 地图引用
   */
  function handleTrackStatus(status: number, trackLineInstance: any, mapRef: Ref<any>): void {
    if (!window.Track) return;
    
    // 记录日志
    const logMessage = TRACK_STATUS_LOG_MAP[status];
    if (logMessage) {
      logger.info(logMessage, { component: 'TrackViewer' });
    }
    
    // 根据状态处理视角跟踪
    switch(status) {
      case window.Track.StatusCodes.PLAY:
      case window.Track.StatusCodes.RESUME:
        // 启用视角跟随
        followingEnabled.value = true;
        isPlaying.value = true;
        break;
        
      case window.Track.StatusCodes.PAUSE:
        isPlaying.value = false;
        break;

      case window.Track.StatusCodes.STOP:
      case window.Track.StatusCodes.FINISH:
        // 禁用视角跟随
        followingEnabled.value = false;
        isPlaying.value = false;
        
        // 轨迹结束时调整地图视野以显示整个轨迹
        adjustMapViewToShowTrack(trackLineInstance, mapRef);
        break;
        
      default:
        break;
    }
  }

  /**
   * 调整地图视野以显示整个轨迹
   * @param trackLineInstance 轨迹线实例
   * @param mapRef 地图引用
   */
  function adjustMapViewToShowTrack(trackLineInstance: any, mapRef: Ref<any>): void {
    if (trackLineInstance && mapRef?.value?.map) {
      const box = trackLineInstance.getBBox();
      if (box) {
        const bounds = [
          new window.BMapGL.Point(box[0], box[1]), 
          new window.BMapGL.Point(box[2], box[3])
        ];
        mapRef.value.map.setViewport(bounds);
        logger.info('轨迹播放结束，调整地图视野', { component: 'TrackViewer' });
      }
    }
  }

  /**
   * 清除轨迹视图
   */
  function clearTrackView(): void {
    // 禁用视角跟随
    followingEnabled.value = false;
    
    if (track.value) {
      clearTrack(track.value);
      trackLoaded.value = false;
    }
    
    resetTrackData();
  }

  // =================== 播放控制方法 ===================
  
  /**
   * 处理轨迹播放
   * @param trackViewerRef 轨迹查看器引用
   */
  const handlePlayTrack = (trackViewerRef: Ref<any>) => {
    if (!isPlaying.value && trackLoaded.value) {
      startAnimation();
      isPlaying.value = true;
    }
  };

  /**
   * 处理轨迹暂停
   * @param trackViewerRef 轨迹查看器引用
   */
  const handlePauseTrack = (trackViewerRef: Ref<any>) => {
    if (isPlaying.value && trackLoaded.value) {
      pauseAnimation();
      isPlaying.value = false;
    }
  };

  /**
   * 轨迹播放位置调整
   * @param percent 百分比位置
   */
  const handleSeekTrack = (percent: number) => {
    if (trackPoints.value.length === 0) return;
    
    // 根据百分比计算实际索引
    const max = trackPoints.value.length - 1;
    const index = Math.round(max * (percent / 100));
    
    currentIndex.value = index;
  };

  /**
   * 播放速度调整
   * @param speed 速度值
   */
  const handleSpeedChange = (speed: number) => {
    if (trackLine.value && typeof trackLine.value.setSpeedMode === 'function') {
      trackLine.value.setSpeedMode(speed);
    }
    playSpeed.value = speed;
  };

  /**
   * 重置轨迹播放
   */
  const handleResetTrack = () => {
    currentIndex.value = 0;
    isPlaying.value = false;
    stopAnimation();
  };
  
  /**
   * 处理完整轨迹加载流程
   * @param mapRef 地图引用
   */
  const handleTrackLoaded = async (mapRef: Ref<any>) => {
    if (shouldLoadTrack.value && deviceId.value) {
      const params: TrackQueryParams = {
        deviceId: deviceId.value,
        startTime: startTime.value,
        endTime: endTime.value
      };
      
      const result = await fetchTrackData(params);
      
      if (result && track.value) {
        await drawTrack(result.trackPointsData, track.value, mapRef);
        shouldLoadTrack.value = false;
        return true;
      }
    }
    return false;
  };
  
  // 返回所有状态和方法
  return {
    // 查询状态
    startTime,
    endTime,
    deviceId,
    shouldLoadTrack,
    
    // 轨迹状态
    track,
    trackLoaded,
    loading,
    error,
    trackPoints,
    trackPointsCount,
    totalDistance,
    formattedDistance,
    
    // 播放状态
    isPlaying,
    currentIndex,
    playSpeed,
    followingEnabled,
    showTrackViewer,
    
    // TrackAnimation方法
    trackLine,
    setTrackLine,
    startAnimation,
    pauseAnimation,
    resumeAnimation,
    stopAnimation,
    
    // 数据管理方法
    resetTrackData,
    prepareTrackQuery,
    fetchTrackData,
    loadTrackData,
    handleTrackLoaded,
    handleTrackError,
    
    // 轨迹渲染方法
    drawTrack,
    handleTrackStatus,
    clearTrackView,
    
    // 播放控制方法
    handlePlayTrack,
    handlePauseTrack,
    handleSeekTrack,
    handleSpeedChange,
    handleResetTrack
  };
} 